<template>
    <div class="w">
        <el-tree :ref="treeNameRef" node-key="id" show-checkbox class="el-tree" :indent="20" :data="menuTree"
            :highlight-current="true" :default-expand-all="true" :expand-on-click-node="false"
            :default-checked-keys="menuIds" @check="handleCheckChange" @node-expand="handleExpand"
            @check-change="checkChange">
            <template #default="{ node, data }">
                <span class="custom-tree-node">
                    <span>
                        <el-icon-render v-if="data.meta?.elIcon" :elIcon="data.meta?.elIcon"></el-icon-render>
                    </span>
                    <span>
                        {{ data.meta?.label }}
                    </span>
                </span>
            </template>
        </el-tree>
    </div>
    <!-- :props="defaultProps" -->
</template>

<script lang="ts">

import { Menu, type MenuInfo } from '@/apis/menu/index'
import { type RequestCode } from '@/server/base'
import elIconRender from '@/components/render/el-icon-render'

export default {
    name: 'menuCheck',
    components: { elIconRender },
    props: {
        modelValue: { type: Array, default: () => { return [] } },
    },
    emits: ['update:modelValue'],
    data() {
        return {
            treeNameRef: 'menuTree',

            menuTree: [],
        }
    },
    computed: {
        menuIds: {
            get() {
                return this.modelValue
            },
            set(val: []) {
                this.$emit('update:modelValue', val);
            }
        }
    },
    methods: {

        getMenuTree() {
            Menu.list()
                .then((res: RequestCode) => {
                    this.menuTree = this.getTreeMenu(res.data, 0)
                })
                .catch(() => {
                })
        },
        checkChange(checkData: any, isCheck: boolean, childrenIsCheck: boolean) {
            this.menuIds = (this.$refs[this.treeNameRef] as any).getCheckedKeys(false);
        },
        getTreeMenu(data: any, parentId: number | string = 0) {
            const children = data
                .filter((item: { parentId: number | string }) => item.parentId == parentId)
                .map(
                    (item: {
                        id: string | number
                        item: string
                        label?: string
                        children?: any[]
                        path: string
                        meta: string
                        component: any
                    }) => {
                        item.path = parentId == 0 ? `/${item.path}` : item.path
                        // if (item.item) {
                        //   //@vite-ignore
                        //   item.component = defineAsyncComponent(() => import(`@/${item.item}`))
                        // }
                        const meta = eval(`(${item.meta})`) as any
                        item.meta = meta
                        item.label = meta.label;
                        item.children = this.getTreeMenu(data, item.id)
                        return item
                    }
                )
            return children
        },
        setRequiredNodeChecked(data: any) {
            for (let i = 0; i < data.length; i++) {
                if (data[i].type) {
                    (this.$refs as any).tree.setChecked(data[i].code, true)
                }
            }
        },
        setNodeUnChecked(data: any) {
            for (let i = 0; i < data.length; i++) {
                (this.$refs as any).tree.setChecked(data[i].code, false)
            }
        },
        fetchCheckedNodeParent(data: any, findKey: any, callback: any) {
            for (let i = 0; i < data.length; i++) {
                const item = data[i]
                if (item.code && item.code === findKey) {
                    callback(data)
                    return true
                }
                if (item.childrens && item.childrens.length) {
                    const result = this.fetchCheckedNodeParent(item.childrens, findKey, callback)
                    if (result) {
                        return true
                    }
                }
            }
            return false
        },
        checkRequired(currentData: any, checkedKeys: any, halfCheckedNodes: any) {
            const currentKey = currentData.code
            const currentType = currentData.type
            if (checkedKeys.includes(currentKey)) {
                // 当前选中
                this.fetchCheckedNodeParent(halfCheckedNodes, currentKey, this.setRequiredNodeChecked)
            } else if (currentType) {
                // 取消选中，但当前项是必选项（如果取消勾选的是列表，那么其余同级节点全部取消勾选）
                this.fetchCheckedNodeParent(halfCheckedNodes, currentKey, this.setNodeUnChecked)
            }
        },
        // 点击节点
        handleCheckChange(data: any, node: any) {
            // this.checkRequired(data, node.checkedKeys, node.halfCheckedNodes)
        },
        handleExpand(currentData: any, currentNode: any, current: any) {

        }
    },
    created() {
        this.getMenuTree();
    }
}
</script>

<style lang="scss" scoped></style>